package com.fayou.algorithm.queue;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class AxinBlockQueue<T> {
    private List<T> container = new ArrayList<>();

    private Lock lock = new ReentrantLock();

    private final Condition isNull = lock.newCondition();

    private final Condition isFull = lock.newCondition();

    private volatile int capacity;

    private volatile int size;

    public AxinBlockQueue(int capacity) {
        this.capacity = capacity;
    }


    public void add(T data) {
        try {
            lock.lock();
            try {
                while (size >= capacity) {
                    System.out.println("阻塞队列满了");

                    isFull.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                isFull.signal();
            }

            ++size;
            container.add(data);
            isNull.signal();
        } catch (Exception e) {
            e.printStackTrace();
            lock.unlock();
        }
    }

    public T take() {
        try {
            lock.lock();
            try {
                while (size == 0) {
                    System.out.println("阻塞队列空了");
                    isFull.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                isNull.signal();
            }
            --size;
            T data = container.remove(0);

            isFull.signal();
            return data;
        } catch (Exception e) {
            e.printStackTrace();

            lock.unlock();
        }
        return null;
    }
}
